package org.gavin.core.controller;

import com.alibaba.fastjson2.JSONObject;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.gavin.core.constant.CommonConst;
import org.gavin.core.domain.R;
import org.gavin.core.enums.CommonStatus;
import org.gavin.core.exception.DataException;
import org.gavin.core.exception.ParamException;
import org.gavin.core.utils.JsonUtils;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@RestController
public class CustomErrorController extends BasicErrorController {

    public CustomErrorController(ErrorAttributes errorAttributes) {
        super(errorAttributes, new ErrorProperties());
    }

    @Override
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        // jdk >= 17
        Object obj = request.getAttribute("jakarta.servlet.error.exception");
        // jdk < 17
        // obj = request.getAttribute("javax.servlet.error.exception");
        Map<String, Object> map = new HashMap<>();
        Integer code = CommonStatus.NO_PATH_FOUND_ERROR.getCode();
        String msg =  CommonStatus.NO_PATH_FOUND_ERROR.getMsg();
        if(obj != null){
            if(obj instanceof ParamException e){
                code = e.getCode();
                msg = e.getMsg();
            }
            if(obj instanceof DataException e){
                code = e.getCode();
                msg = e.getMsg();
            }
        }
        map.put("code",code);
        map.put("msg",msg);
        return
                new ResponseEntity<>(
                        map,
                        HttpStatus.OK
                );
    }

    @Override
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
        ModelAndView view = new ModelAndView();
        response.setContentType(CommonConst.CONTENT_TYPE_JSON);
        response.setCharacterEncoding(CommonConst.CHARACTER_ENCODING);
        JSONObject json = new JSONObject();
        json.put(CommonConst.SERVER_TIME, System.currentTimeMillis());
        try( PrintWriter writer =  response.getWriter()) {
            response.setStatus(200);
            R<Object> fail = R.fail(CommonStatus.NO_PATH_FOUND_ERROR);
            writer.write(JsonUtils.mapper.writeValueAsString(fail));
        } catch (IOException e) {
            return view;
        }
        return view;
    }

}
